package service

import (
	"encoding/json"
	"fmt"
	ClickHouse "gin/database"
	"gin/model"
	"gin/types"
	"strconv"
	"strings"
)

type TaskRepair struct {
}

type entityWithModuleCode struct {
	model.Entity
	ModuleCode string `json:"module_code"`
}

// getEntityListDownstreamEntityList 查询实体列表关联的实体列表
func (r *TaskRepair) getEntityListDownstreamEntityList(entityIdList []int64) (res map[int64][]model.Entity, err error) {
	var entityList []entityWithModuleCode
	err = ClickHouse.DB.Model(&model.Entity{}).Joins("LEFT JOIN module on entity.module_id = module.id").
		Where("id in ?", entityIdList).
		Select("entity.*,module.code as module_code").Find(&entityList).Error
	if err != nil {
		return
	}
	res = make(map[int64][]model.Entity, 0)
	for _, entity := range entityList {
		switch entity.ModuleCode {
		case "design":
			res[int64(entity.Id)], err = r.getDesignDownstreamEntities(entity.Entity)
			break
		case "asset":
			res[int64(entity.Id)], err = r.getAssetDownstreamEntities(entity.Entity)
			break
		case "level":
			res[int64(entity.Id)], err = r.getLevelDownstreamEntities(entity.Entity)
			break
		case "sequence":
			res[int64(entity.Id)], err = r.getSequenceListDownstreamEntities(entity.Entity.ProjectId, []model.Entity{entity.Entity})
			break
		case "shot":
		default:
		}
		if err != nil {
			return
		}
		res[int64(entity.Id)] = append(res[int64(entity.Id)], entity.Entity)
	}

	return
}

// GetEffectedTask 查询受影响的任务
func (r *TaskRepair) GetEffectedTask(req types.GetEffectedTaskReq, tenantId int64) (res types.GetEffectedTaskRes, err error) {

	var taskList []model.Task
	err = ClickHouse.DB.Model(&model.Task{}).Where("id in ?", req.TaskIdList).Find(&taskList).Error
	if err != nil {
		return
	}

	var project model.Project
	err = ClickHouse.DB.Model(&model.Project{}).Where("id = ?", req.ProjectId).Find(&project).Error
	if err != nil {
		return
	}
	var entityIdList []int64
	var entityIdMap = make(map[int64]bool, 0)
	var stepIdList []int64
	var stepIdMap = make(map[int64]bool, 0)
	for _, task := range taskList {
		if task.EntityId <= 0 || task.StepId <= 0 {
			continue
		}
		if _, ok := stepIdMap[task.StepId]; !ok {
			stepIdList = append(stepIdList, task.StepId)
			stepIdMap[task.StepId] = true
		}
		if _, ok := entityIdMap[task.EntityId]; !ok {
			entityIdList = append(entityIdList, task.EntityId)
			entityIdMap[task.EntityId] = true
		}
	}
	if len(entityIdList) == 0 {
		return
	}
	// 工序子级关系
	stepsChildren, err := GetStepsChildren(project.ProjectTemplateId, stepIdList, 30)
	if err != nil {
		return
	}
	var stepChildrenIdsMap = make(map[int64][]int64, 0)
	for i, stepList := range stepsChildren {
		stepChildrenIdsMap[i] = make([]int64, len(stepList))
		for si, step := range stepList {
			stepChildrenIdsMap[i][si] = step.Id
		}
	}

	// 实体关联实体
	relatedEntityList, err := r.getEntityListDownstreamEntityList(entityIdList)
	if err != nil {
		return
	}

	var relatedEntityIdsMap = make(map[int64][]uint64, 0)
	for i, entities := range relatedEntityList {
		relatedEntityIdsMap[i] = make([]uint64, len(entities))
		for ei, entity := range entities {
			relatedEntityIdsMap[i][ei] = entity.Id
		}
	}

	var matched = false
	relatedTaskFilter := ClickHouse.DB
	for _, task := range taskList {
		if task.EntityId <= 0 || task.StepId <= 0 {
			continue
		}
		if _, ok := relatedEntityIdsMap[task.EntityId]; !ok || len(relatedEntityIdsMap[task.EntityId]) == 0 {
			continue
		}
		if _, ok := stepChildrenIdsMap[task.StepId]; !ok || len(stepChildrenIdsMap[task.StepId]) == 0 {
			continue
		}
		matched = true
		relatedTaskFilter = relatedTaskFilter.Or("t.entity_id in ? and t.step_id in ?", relatedEntityIdsMap[task.EntityId], stepChildrenIdsMap[task.StepId])
	}
	if !matched {
		return
	}
	dataBaseFilter := ClickHouse.DB.Where("t.tenant_id = ? and t.project_id = ?", tenantId, req.ProjectId)
	statusFilter := ClickHouse.DB.Where("ss.correspond in ?", []string{"in_progress", "daily", "feedback", "done"})
	err = ClickHouse.DB.Table("task t").Joins("LEFT JOIN entity e on e.id = t.entity_id " +
		"LEFT JOIN step s on s.id = t.step_id LEFT JOIN step_category sc on sc.id = t.step_category_id LEFT JOIN user u on u.id = t.executor " +
		"LEFT JOIN tenant tt on t.executor_tenant_id = tt.id " +
		"LEFT JOIN status ss on ss.id = simpleJSONExtractInt(t.json,'task_status') ").
		Where(dataBaseFilter).Where(relatedTaskFilter).Where(statusFilter).
		Select("t.id as id,e.initial_episode_code as initial_episode_code,e.showings_number as showings_number,e.name as entity_name" +
			",multiIf(e.module_id = 43, simpleJSONExtractString(e.json, 'asset_grade'), e.module_id = 44,simpleJSONExtractString(e.json, 'level_grade'), e.module_id = 70,simpleJSONExtractString(e.json, 'design_grade'), '-') as entity_grade" +
			",multiIf(e.module_id = 43, simpleJSONExtractString(e.json, 'asset_category'), e.module_id = 44,simpleJSONExtractString(e.json, 'level_category'), e.module_id = 70,simpleJSONExtractString(e.json, 'design_category'), '-') as entity_category" +
			",sc.name as step_category_name,s.name as step_name,tt.name as executor_company_name," +
			"if(t.executor_tenant_id = t.tenant_id, u.name, '-') as executor_name," +
			"ss.name as task_status,t.plan_start_time as task_plan_start_time,t.plan_end_time as task_plan_end_time, " +
			"if(has([43,44,70], e.module_id), 'asset', 'shot') as merge_module_code").
		Find(&res).
		Error
	return
}

// getDesignDownstreamEntities 查询概念关联的实体
func (r *TaskRepair) getDesignDownstreamEntities(entity model.Entity) (res []model.Entity, err error) {
	res = make([]model.Entity, 0)
	var designJson model.DesignJson
	_ = json.Unmarshal(entity.Json, &designJson)
	var generatedEntity model.Entity
	var queryWhere = ClickHouse.DB
	if designJson.DesignCategory == "关卡" {
		queryWhere = queryWhere.Where("simpleJSONExtractInt(json,'level_design') = ?", entity.Id)
	} else {
		queryWhere = queryWhere.Where("simpleJSONExtractInt(json,'asset_design') = ?", entity.Id)
	}

	err = ClickHouse.DB.Model(&model.Entity{}).Where(queryWhere).Find(&generatedEntity).Error
	if err != nil || generatedEntity.Id == 0 {
		return
	}
	res = append(res, generatedEntity)

	var generatedEntityRelatedEntities []model.Entity
	if designJson.DesignCategory == "关卡" {
		generatedEntityRelatedEntities, err = r.getLevelDownstreamEntities(generatedEntity)
	} else {
		generatedEntityRelatedEntities, err = r.getAssetDownstreamEntities(generatedEntity)
	}
	if len(generatedEntityRelatedEntities) > 0 {
		res = append(res, generatedEntityRelatedEntities...)
	}
	return
}

// getLevelDownstreamEntities 查询关卡关联的实体
func (r *TaskRepair) getLevelDownstreamEntities(entity model.Entity) (res []model.Entity, err error) {
	relationWhere := ClickHouse.DB.
		Where("module_id = (select id from module where code = 'shot' limit 1) and has(splitByChar(',', ifNull(simpleJSONExtractString(json, 'shot_level'), '')), ?)", strconv.FormatUint(entity.Id, 10)).
		Or("module_id = (select id from module where code = 'sequence' limit 1) and has(splitByChar(',', ifNull(simpleJSONExtractString(json, 'sequence_level'), '')), ?)", strconv.FormatUint(entity.Id, 10))
	var relationEntityWithModuleCode []entityWithModuleCode
	err = ClickHouse.DB.Model(&model.Entity{}).
		Joins("LEFT JOIN module on module.id = entity.module_id").
		Where("project_id = ? ", entity.ProjectId).Where(relationWhere).Select("entity.*,module.code as module_code").
		Find(&relationEntityWithModuleCode).Error

	if err != nil {
		return
	}
	var entityMap = make(map[uint64]bool)
	var sequenceList = make([]model.Entity, 0)
	for _, re := range relationEntityWithModuleCode {
		res = append(res, re.Entity)
		entityMap[re.Id] = true
		if re.ModuleCode == "sequence" {
			sequenceList = append(sequenceList, re.Entity)
		}
	}
	// 如果存在序列列表 那么需要查询序列关联的镜头列表
	if len(sequenceList) > 0 {
		shotEntityList, errOccurred := r.getSequenceListDownstreamEntities(entity.ProjectId, sequenceList)
		if errOccurred != nil {
			err = errOccurred
			return
		}
		for _, m := range shotEntityList {
			if _, ok := entityMap[m.Id]; !ok {
				res = append(res, m)
			}
		}
	}

	return
}

// getAssetDownstreamEntities 查询资产关联的实体
func (r *TaskRepair) getAssetDownstreamEntities(entity model.Entity) (res []model.Entity, err error) {
	/**
	 * 查询关联的关卡,镜头,序列
	 * 序列,关卡 需要再次查询关联的实体
	 */
	var relationEntityWithModuleCode []entityWithModuleCode
	relationWhere := ClickHouse.DB.
		Where("module_id = (select id from module where code = 'shot' limit 1) and has(splitByChar(',', ifNull(simpleJSONExtractString(json, 'shot_asset'), '')), ?)", strconv.FormatUint(entity.Id, 10)).
		Or("module_id = (select id from module where code = 'sequence' limit 1) and has(splitByChar(',', ifNull(simpleJSONExtractString(json, 'sequence_asset'), '')), ?)", strconv.FormatUint(entity.Id, 10)).
		Or("module_id = (select id from module where code = 'level' limit 1) and has(splitByChar(',', ifNull(simpleJSONExtractString(json, 'level_asset'), '')), ?)", strconv.FormatUint(entity.Id, 10))
	err = ClickHouse.DB.Model(&model.Entity{}).
		Joins("LEFT JOIN module on module.id = entity.module_id").
		Where("project_id = ?", entity.ProjectId).
		Where(relationWhere).
		Select("entity.*,module.code as module_code").
		Find(&relationEntityWithModuleCode).Error

	if err != nil {
		return
	}

	var entityMap = make(map[uint64]bool)
	var sequenceList = make([]model.Entity, 0)
	var levelList = make([]model.Entity, 0)
	for _, re := range relationEntityWithModuleCode {
		res = append(res, re.Entity)
		entityMap[re.Id] = true
		if re.ModuleCode == "sequence" {
			sequenceList = append(sequenceList, re.Entity)
		} else if re.ModuleCode == "level" {
			levelList = append(levelList, re.Entity)
		}
	}
	// 如果存在序列列表 那么需要查询序列关联的镜头列表
	if len(sequenceList) > 0 {
		shotEntityList, errOccurred := r.getSequenceListDownstreamEntities(entity.ProjectId, sequenceList)
		if errOccurred != nil {
			err = errOccurred
			return
		}
		for _, m := range shotEntityList {
			if _, ok := entityMap[m.Id]; !ok {
				res = append(res, m)
				entityMap[m.Id] = true
			}
		}
	}

	// 如果存在关卡列表 那么需要查询关卡关联的镜头列表
	if len(levelList) > 0 {
		for _, level := range levelList {
			levelRelatedEntityList, errOccurred := r.getLevelDownstreamEntities(level)
			if errOccurred != nil {
				return
			}
			for _, levelRelatedEntity := range levelRelatedEntityList {
				if _, ok := entityMap[levelRelatedEntity.Id]; !ok {
					res = append(res, levelRelatedEntity)
					entityMap[levelRelatedEntity.Id] = true
				}
			}
		}
	}

	return
}

// getSequenceListDownstreamEntities 查询序列关联的实体列表
func (r *TaskRepair) getSequenceListDownstreamEntities(projectId int64, sequenceList []model.Entity) (res []model.Entity, err error) {
	var sequenceIdList = make([]uint64, len(sequenceList))
	for i, entity := range sequenceList {
		sequenceIdList[i] = entity.Id
	}

	err = ClickHouse.DB.Model(&model.Entity{}).Where("project_id = ?", projectId).Where("entity_id in ?", sequenceIdList).Find(&res).Error
	return
}

// getEntityListUpstreamEntityList 查询实体列表关联的上游实体列表
func (r *TaskRepair) getEntityListUpstreamEntityList(entityIdList []int64) (res map[int64][]model.Entity, err error) {
	var entityList []entityWithModuleCode
	err = ClickHouse.DB.Model(&model.Entity{}).Joins("LEFT JOIN module on entity.module_id = module.id").
		Where("id in ?", entityIdList).
		Select("entity.*,module.code as module_code").Find(&entityList).Error
	if err != nil {
		return
	}
	res = make(map[int64][]model.Entity, 0)
	for _, entity := range entityList {
		switch entity.ModuleCode {
		case "asset":
			res[int64(entity.Id)], err = r.getAssetUpstreamEntities(entity.Entity)
			break
		case "level":
			res[int64(entity.Id)], err = r.getLevelUpstreamEntities(entity.Entity)
			break
		case "sequence":
			res[int64(entity.Id)], err = r.getSequenceUpstreamEntities(entity.Entity)
			break
		case "shot":
			res[int64(entity.Id)], err = r.getShotUpstreamEntities(entity.Entity)
			break
		default:
		}
		if err != nil {
			return
		}
		res[int64(entity.Id)] = append(res[int64(entity.Id)], entity.Entity)
	}

	return
}

// GetUpstreamTasks 获得任务上游任务列表
func (r *TaskRepair) GetUpstreamTasks(taskId uint64) (res types.GetUpstreamTasksRes, err error) {
	var task model.Task
	err = ClickHouse.DB.Model(&model.Task{}).Where("id = ?", taskId).Find(&task).Error
	if err != nil || task.Id == 0 {
		return
	}
	var project model.Project
	err = ClickHouse.DB.Model(&model.Project{}).Where("id = ?", task.ProjectId).Find(&project).Error
	if err != nil {
		return
	}
	// 上游工序
	upstreamStepList, err := GetStepParents(project.ProjectTemplateId, task.StepId)
	if len(upstreamStepList) == 0 {
		return
	}
	upstreamStepIdList := make([]int64, len(upstreamStepList))
	for i, item := range upstreamStepList {
		upstreamStepIdList[i] = item.Id
	}
	relatedMap, err := r.getEntityListUpstreamEntityList([]int64{task.EntityId})
	if _, ok := relatedMap[task.EntityId]; !ok {
		return
	}
	if len(relatedMap[task.EntityId]) == 0 {
		return
	}
	entityIdList := make([]uint64, len(relatedMap[task.EntityId]))
	for i, entity := range relatedMap[task.EntityId] {
		entityIdList[i] = entity.Id
	}

	dataBaseFilter := ClickHouse.DB.Where("t.tenant_id = ? and t.project_id = ?", task.TenantId, task.ProjectId)
	err = ClickHouse.DB.Table("task t").
		Joins("LEFT JOIN entity e on e.id = t.entity_id").
		Where(dataBaseFilter).
		Where("t.entity_id in ? and t.step_id in ?", entityIdList, upstreamStepIdList).
		Select("t.*").
		Find(&res).
		Error

	return

}

// getAssetUpstreamEntities 查询资产上游实体列表
func (r *TaskRepair) getAssetUpstreamEntities(entity model.Entity) (res []model.Entity, err error) {
	var jsonData model.AssetJson
	_ = json.Unmarshal(entity.Json, &jsonData)
	designId := IntVal(jsonData.AssetDesignSource)
	if designId == 0 {
		return
	}

	err = ClickHouse.DB.Model(&model.Entity{}).Where("id = ?", designId).Find(&res).Error
	return
}

// getAssetsUpstreamEntities 查询资产上游实体列表
func (r *TaskRepair) getAssetsUpstreamEntities(entityList []model.Entity) (res []model.Entity, err error) {
	var designIdList []int64
	var jsonData model.AssetJson

	for _, entity := range entityList {
		_ = json.Unmarshal(entity.Json, &jsonData)
		designId := IntVal(jsonData.AssetDesignSource)
		if designId > 0 {
			designIdList = append(designIdList, designId)
		}
	}
	if len(designIdList) > 0 {
		err = ClickHouse.DB.Model(&model.Entity{}).Where("id in ?", designIdList).Find(&res).Error
	}
	return
}

// getLevelUpstreamEntities 查询关卡上游实体列表
func (r *TaskRepair) getLevelUpstreamEntities(entity model.Entity) (res []model.Entity, err error) {
	var jsonData model.LevelJson
	_ = json.Unmarshal(entity.Json, &jsonData)

	designId := IntVal(jsonData.LevelDesignSource)

	if designId == 0 {
		return
	}

	err = ClickHouse.DB.Model(&model.Entity{}).Where("id = ?", designId).Find(&res).Error
	return
}

// getLevelsUpstreamEntities 查询关卡上游实体列表
func (r *TaskRepair) getLevelsUpstreamEntities(entityList []model.Entity) (res []model.Entity, err error) {
	var designIdList []int64
	var jsonData model.LevelJson
	for _, entity := range entityList {
		_ = json.Unmarshal(entity.Json, &jsonData)
		designId := IntVal(jsonData.LevelDesignSource)
		if designId > 0 {
			designIdList = append(designIdList, designId)
		}
	}
	if len(designIdList) > 0 {
		err = ClickHouse.DB.Model(&model.Entity{}).Where("id in ?", designIdList).Find(&res).Error
	}
	return
}

func (r *TaskRepair) getSequenceUpstreamEntities(entity model.Entity) (res []model.Entity, err error) {
	var jsonData model.SequenceJson
	_ = json.Unmarshal(entity.Json, &jsonData)
	var assetIdList = make([]int64, 0)
	for _, s := range strings.Split(jsonData.SequenceAsset, ",") {
		v, _ := strconv.ParseInt(s, 10, 64)
		if v > 0 {
			assetIdList = append(assetIdList, v)
		}
	}
	if len(assetIdList) > 0 {
		var assetList []model.Entity
		err = ClickHouse.DB.Model(&model.Entity{}).Where("id in ?", assetIdList).Find(&assetList).Error
		if err != nil {
			return
		}
		if len(assetList) > 0 {
			res = append(res, assetList...)
			var relatedAssetEntity []model.Entity
			relatedAssetEntity, err = r.getAssetsUpstreamEntities(assetList)
			if err != nil {
				return
			}
			if len(relatedAssetEntity) > 0 {
				res = append(res, relatedAssetEntity...)
			}
		}
	}
	var levelIdList = make([]int64, 0)
	for _, s := range strings.Split(jsonData.SequenceLevel, ",") {
		v, _ := strconv.ParseInt(s, 10, 64)
		if v > 0 {
			levelIdList = append(levelIdList, v)
		}
	}
	if len(levelIdList) > 0 {
		var levelList []model.Entity
		err = ClickHouse.DB.Model(&model.Entity{}).Where("id in ?", levelIdList).Find(&levelList).Error
		if err != nil {
			return
		}
		if len(levelList) > 0 {
			res = append(res, levelList...)
			var relatedLevelEntity []model.Entity
			relatedLevelEntity, err = r.getAssetsUpstreamEntities(levelList)
			if err != nil {
				return
			}
			if len(relatedLevelEntity) > 0 {
				res = append(res, relatedLevelEntity...)
			}
		}
	}
	return
}

// getShotUpstreamEntities 查询镜头上游实体列表
func (r *TaskRepair) getShotUpstreamEntities(entity model.Entity) (res []model.Entity, err error) {
	var jsonData model.ShotJson
	_ = json.Unmarshal(entity.Json, &jsonData)
	var assetIdList = make([]int64, 0)
	for _, s := range strings.Split(jsonData.ShotAsset, ",") {
		v, _ := strconv.ParseInt(s, 10, 64)
		if v > 0 {
			assetIdList = append(assetIdList, v)
		}
	}
	if len(assetIdList) > 0 {
		var assetList []model.Entity
		err = ClickHouse.DB.Model(&model.Entity{}).Where("id in ?", assetIdList).Find(&assetList).Error
		if err != nil {
			return
		}
		if len(assetList) > 0 {
			res = append(res, assetList...)
			var relatedAssetEntity []model.Entity
			relatedAssetEntity, err = r.getAssetsUpstreamEntities(assetList)
			if err != nil {
				return
			}
			if len(relatedAssetEntity) > 0 {
				res = append(res, relatedAssetEntity...)
			}
		}
	}
	var levelIdList = make([]int64, 0)
	for _, s := range strings.Split(jsonData.ShotLevel, ",") {
		v, _ := strconv.ParseInt(s, 10, 64)
		if v > 0 {
			levelIdList = append(levelIdList, v)
		}
	}
	if len(levelIdList) > 0 {
		var levelList []model.Entity
		err = ClickHouse.DB.Model(&model.Entity{}).Where("id in ?", levelIdList).Find(&levelList).Error
		if err != nil {
			return
		}
		if len(levelList) > 0 {
			res = append(res, levelList...)
			var relatedLevelEntity []model.Entity
			relatedLevelEntity, err = r.getAssetsUpstreamEntities(levelList)
			if err != nil {
				return
			}
			if len(relatedLevelEntity) > 0 {
				res = append(res, relatedLevelEntity...)
			}
		}
	}
	return
}

// GetEffectedTask 查询受影响的任务
func (r *TaskRepair) GetMultiProjectEffectedTask(taskIdList []int64, tenantId int64) (res types.GetEffectedTaskRes, err error) {

	var taskList []model.Task
	err = ClickHouse.DB.Model(&model.Task{}).Where("id in ?", taskIdList).Find(&taskList).Error
	if err != nil {
		return
	}

	var projectIds []int64
	projectMap := map[int64]int64{}
	for _, taskItem := range taskList {
		if _, ok := projectMap[taskItem.ProjectId]; !ok {
			projectIds = append(projectIds, taskItem.ProjectId)
			projectMap[taskItem.ProjectId] = taskItem.ProjectId
		}
	}

	var project []model.Project
	err = ClickHouse.DB.Model(&model.Project{}).Where("id in ?", projectIds).Find(&project).Error
	if err != nil {
		return
	}
	//var entityIdList []int64
	//var entityIdMap = make(map[int64]bool, 0)
	//var stepIdList []int64
	//var stepIdMap = make(map[int64]bool, 0)

	var projectEntityIdMap = make(map[int64]map[int64]int64, 0)
	var projectEntityIdList = make(map[int64][]int64, 0)
	var projectStepIdMap = make(map[int64]map[int64]int64, 0)

	for _, task := range taskList {
		if task.ProjectId <= 0 || task.EntityId <= 0 || task.StepId <= 0 {
			continue
		}
		if stepIdMap, ok := projectStepIdMap[task.ProjectId]; !ok {
			projectStepIdMap[task.ProjectId] = map[int64]int64{
				task.StepId: task.StepId,
			}
		} else if _, stepOk := stepIdMap[task.StepId]; !stepOk {
			projectStepIdMap[task.ProjectId][task.StepId] = task.StepId
		}

		if entityIdMap, ok := projectEntityIdMap[task.ProjectId]; !ok {
			projectEntityIdMap[task.ProjectId] = map[int64]int64{
				task.EntityId: task.EntityId,
			}
			projectEntityIdList[task.ProjectId] = []int64{task.EntityId}
		} else if _, entityOk := entityIdMap[task.EntityId]; !entityOk {
			projectEntityIdMap[task.ProjectId][task.EntityId] = task.EntityId
			projectEntityIdList[task.ProjectId] = append(projectEntityIdList[task.ProjectId], task.EntityId)
		}
	}

	if len(projectEntityIdMap) == 0 {
		return res, err
	}

	projectTemplateMap := map[int64]int64{}
	for _, projectItem := range project {
		projectTemplateMap[int64(projectItem.Id)] = projectItem.ProjectTemplateId
	}

	// 工序子级关系
	projectStepsChildren, err := GetMultiProjectStepsChildren(projectTemplateMap, projectStepIdMap, 30)
	if err != nil {
		return res, err
	}

	var projectEffectedTask types.GetEffectedTaskRes
	for projectId, stepsChildren := range projectStepsChildren {
		var stepChildrenIdsMap = make(map[int64][]int64, 0)
		for i, stepList := range stepsChildren {
			stepChildrenIdsMap[i] = make([]int64, len(stepList))
			for si, step := range stepList {
				stepChildrenIdsMap[i][si] = step.Id
			}
		}

		fmt.Println(stepChildrenIdsMap)

		entityIdList := projectEntityIdList[projectId]

		// 实体关联实体
		relatedEntityList, err := r.getEntityListDownstreamEntityList(entityIdList)
		if err != nil {
			return res, err
		}

		var relatedEntityIdsMap = make(map[int64][]uint64, 0)
		for i, entities := range relatedEntityList {
			relatedEntityIdsMap[i] = make([]uint64, len(entities))
			for ei, entity := range entities {
				relatedEntityIdsMap[i][ei] = entity.Id
			}
		}

		var matched = false
		relatedTaskFilter := ClickHouse.DB
		for _, task := range taskList {
			if task.EntityId <= 0 || task.StepId <= 0 {
				continue
			}
			if _, ok := relatedEntityIdsMap[task.EntityId]; !ok || len(relatedEntityIdsMap[task.EntityId]) == 0 {
				continue
			}
			if _, ok := stepChildrenIdsMap[task.StepId]; !ok || len(stepChildrenIdsMap[task.StepId]) == 0 {
				continue
			}
			matched = true
			relatedTaskFilter = relatedTaskFilter.Or("t.entity_id in ? and t.step_id in ?", relatedEntityIdsMap[task.EntityId], stepChildrenIdsMap[task.StepId])
		}

		if !matched {
			continue
		}
		dataBaseFilter := ClickHouse.DB.Where("t.tenant_id = ? and t.project_id = ?", tenantId, projectId)
		//statusFilter := ClickHouse.DB.Where("ss.correspond in ?", []string{"in_progress", "daily", "feedback", "done"})
		err = ClickHouse.DB.Table("task t").Joins("LEFT JOIN entity e on e.id = t.entity_id " +
			"LEFT JOIN step s on s.id = t.step_id LEFT JOIN step_category sc on sc.id = t.step_category_id LEFT JOIN user u on u.id = t.executor " +
			"LEFT JOIN tenant tt on t.executor_tenant_id = tt.id " +
			"LEFT JOIN status ss on ss.id = simpleJSONExtractInt(t.json,'task_status') ").
			Where(dataBaseFilter).Where(relatedTaskFilter).
			Select("t.id as id,e.initial_episode_code as initial_episode_code,e.showings_number as showings_number,e.name as entity_name" +
				",multiIf(e.module_id = 43, simpleJSONExtractString(e.json, 'asset_grade'), e.module_id = 44,simpleJSONExtractString(e.json, 'level_grade'), e.module_id = 70,simpleJSONExtractString(e.json, 'design_grade'), '-') as entity_grade" +
				",multiIf(e.module_id = 43, simpleJSONExtractString(e.json, 'asset_category'), e.module_id = 44,simpleJSONExtractString(e.json, 'level_category'), e.module_id = 70,simpleJSONExtractString(e.json, 'design_category'), '-') as entity_category" +
				",sc.name as step_category_name,s.name as step_name,tt.name as executor_company_name," +
				"if(t.executor_tenant_id = t.tenant_id, u.name, '-') as executor_name," +
				"ss.name as task_status,t.plan_start_time as task_plan_start_time,t.plan_end_time as task_plan_end_time, " +
				"if(has([43,44,70], e.module_id), 'asset', 'shot') as merge_module_code").
			Find(&projectEffectedTask).
			Error

		if err != nil {
			return res, err
		}

		for _, projectEffectedTaskItem := range projectEffectedTask {
			res = append(res, projectEffectedTaskItem)
		}
	}
	return
}

//GetMultiProjectEffectedGroupTask 查询受影响多项目的分组任务
func (r *TaskRepair) GetMultiProjectEffectedGroupTask(req types.GetMultiProjectEffectedGroupTaskReq, tenantId int64) (res types.GetMultiProjectEffectedGroupTaskRes, err error) {
	effectedTask, err := r.GetMultiProjectEffectedTask(req.TaskIdList, tenantId)
	if err != nil {
		return
	}

	var assetEffectedTaskList []types.GetEffectedTaskResItem
	var shotEffectedTaskList []types.GetEffectedTaskResItem
	for _, effectedTaskItem := range effectedTask {
		if effectedTaskItem.MergeModuleCode == "asset" {
			assetEffectedTaskList = append(assetEffectedTaskList, effectedTaskItem)
		} else {
			shotEffectedTaskList = append(shotEffectedTaskList, effectedTaskItem)
		}
	}

	var resItem []types.GetMultiProjectEffectedGroupTaskResItem
	var count int
	if len(assetEffectedTaskList) > 0 {
		resItem = append(resItem, types.GetMultiProjectEffectedGroupTaskResItem{
			ModuleCode:       "asset",
			Count:            int64(len(assetEffectedTaskList)),
			EffectedTaskList: assetEffectedTaskList,
		})
		count += len(assetEffectedTaskList)
	}
	if len(shotEffectedTaskList) > 0 {
		resItem = append(resItem, types.GetMultiProjectEffectedGroupTaskResItem{
			ModuleCode:       "shot",
			Count:            int64(len(shotEffectedTaskList)),
			EffectedTaskList: shotEffectedTaskList,
		})

		count += len(shotEffectedTaskList)
	}

	res = types.GetMultiProjectEffectedGroupTaskRes{
		Count: int64(count),
		List:  resItem,
	}

	return
}
